package com.cf.chat.server;
import com.cf.chat.util.CloseUtil;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.List;
/**
 * @Auther: chenf
 * @Date: 2020/07/28/15:01
 * @Description:
 * 每一个客户端都是条道路
 *    1.输入流
 *    2.输出流
 *    3.接收数据
 *    4.发送数据
 */
public class MyChannel implements Runnable {
    // 定义数据输入流和输出流
    private DataInputStream dis;
    private DataOutputStream dos;
    private boolean flag = true;
    private String channelName;

    /**
     * 定义静态成员变量name
     */
    public static String name;

    /**
     * 将当前客户端传入的数据传递给服务器的输入流和输出流
     */
    public MyChannel(Socket client) {
        try {
            dis = new DataInputStream(client.getInputStream());
            dos = new DataOutputStream(client.getOutputStream());
        } catch (IOException e) {
            // 如果出现异常，关闭当前流
            flag = false;
            CloseUtil.closeAll(dis, dos);
        }
    }

    /**
     * 创建接收数据的方法
     */
    private String receive() {
        String str = "";
        // 将流中的数据传递给str字符串
        try {
            str = dis.readUTF();
        } catch (IOException e) {
            flag = false;
            // 关闭当前流
            CloseUtil.closeAll(dis, dos);
            // 从服务器移除此线程
            Server.list.remove(this);
        }
        return str;
    }

    /**
     * 创建发送数据的方法
     * 将接受到的数据发出去
     */
    private void send(String str) {
        // 如果str非空则发送（str）接收的数据
        if (str != null && str.length() != 0) {
            try {
                dos.writeUTF(str);
                // 刷新输出流
                dos.flush();
            } catch (IOException e) {
                flag = false;
                CloseUtil.closeAll(dis, dos);
                // 如果出现异常，移除当前线程
                Server.list.remove(this);
            }
        }
    }

    /**
     * 创建转发的方法
     * 通过调用sendOther实现多台客户端之间的通信
     */
    private void sendOther() {
        // 接收客户端发来的数据
        String str = this.receive();
        List<MyChannel> list = Server.list;
        // 遍历当前线程集合，将获取的数据发送至除了自身线程以外的其他线程
        for (MyChannel other:list) {
            // 将信息转发给除了自身以外的其他客户端
            if (other == this) {
                continue;
            }
            // 获取当前线程名
            name = Thread.currentThread().getName();
            // 发送数据
            other.send("客户端" + name+ ":" + "\n" + str);
        }
    }

    public String getChannelName() {
        return channelName;
    }

    public void setChannelName(String channelName) {
        this.channelName = channelName;
    }

    /**
     * Server端的run方法
     */
    @Override
    public void run() {
        while (flag) {
            // 调用发送数据的方法
            sendOther();
        }
    }
}